package com.ops.uitl.common;

import com.ops.uitl.data.DataMap;
import com.ops.uitl.data.IData;
import com.ops.uitl.data.IDataset;
import com.ops.uitl.tapestry.BaseData;
import com.ops.uitl.tapestry.BasePage;
import org.apache.log4j.Logger;
import org.apache.tapestry.*;
import org.apache.tapestry.engine.AbstractService;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.IEngineServiceView;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.form.IFormComponent;
import org.apache.tapestry.html.HTMLWriter;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.request.ResponseOutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;

public class AjaxDirectService extends AbstractService implements IEngineService {
    public static final String SERVICE_NAME = "ajaxDirect";
    protected Logger log = Logger.getLogger(this.getClass());
    private static final String STATEFUL_OFF = "0";
    private static final String STATEFUL_ON = "1";
    private static ThreadLocal currentPartIds = new ThreadLocal();
    private static ThreadLocal currentPartWriters = new ThreadLocal();
    protected Map writers = new HashMap();

    public AjaxDirectService() {
    }

    public String getName() {
        return "ajaxDirect";
    }

    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters) {
        String stateful = cycle.getEngine().isStateful()?"1":"0";
        IPage renderPage = cycle.getPage();
        IPage componentPage = component.getPage();
        String[] context = new String[]{stateful, renderPage.getPageName(), componentPage.getPageName(), component.getIdPath()};
        ILink tmp = this.constructLink(cycle, "ajaxDirect", context, parameters, true);
        return tmp;
    }

    public void service(IEngineServiceView engine, IRequestCycle cycle, ResponseOutputStream output) throws IOException, ServletException {
        RequestContext requestContext = cycle.getRequestContext();
        String[] serviceContext = this.getServiceContext(requestContext);
        String stateful = serviceContext[0];
        String renderPageName = serviceContext[1];
        String componentPageName = serviceContext[2];
        String componentPath = serviceContext[3];
        String pageName = null;
        String eventName = null;
        HashSet partIds = null;
        HashSet partIds2 = new HashSet();
        IDirect direct = null;
        String header;
        String var40;
        if("javascript".equals(componentPath)) {
            HttpServletRequest var37 = cycle.getRequestContext().getRequest();
            Enumeration var39 = var37.getParameterNames();

            label374:
            while(true) {
                while(true) {
                    if(!var39.hasMoreElements()) {
                        break label374;
                    }

                    var40 = (String)var39.nextElement();
                    String[] var43;
                    if("pagename".equals(var40)) {
                        var43 = var37.getParameterValues(var40);
                        pageName = var43[0];
                    } else if("eventname".equals(var40)) {
                        var43 = var37.getParameterValues(var40);
                        eventName = var43[0];
                    } else if("partids".equals(var40)) {
                        var43 = var37.getParameterValues(var40);
                        String transferData = var43[0];
                        StringTokenizer partWriters = new StringTokenizer(transferData, ",");

                        while(partWriters.hasMoreTokens()) {
                            header = partWriters.nextToken();
                            partIds2.add(header);
                        }
                    }
                }
            }
        } else {
            IPage e = cycle.getPage(renderPageName);
            cycle.activate(e);
            IPage ajaxData = e;
            if(!componentPageName.equals(renderPageName)) {
                ajaxData = cycle.getPage(componentPageName);
            }

            IComponent xmlData = ajaxData.getNestedComponent(componentPath);

            try {
                direct = (IDirect)xmlData;
            } catch (ClassCastException var34) {
                throw new ApplicationRuntimeException(Tapestry.format("DirectService.component-wrong-type", xmlData.getExtendedId()), xmlData, (ILocation)null, var34);
            }

            if(stateful.equals("1") && direct.isStateful()) {
                HttpSession ajaxDataset = cycle.getRequestContext().getSession();
                if(ajaxDataset == null || ajaxDataset.isNew()) {
                    throw new StaleSessionException(Tapestry.format("DirectService.stale-session-exception", direct.getExtendedId()), direct.getPage());
                }
            }

            currentPartIds.set((Object)null);
            currentPartWriters.set((Object)null);
            if(serviceContext.length > 4) {
                partIds = new HashSet();

                for(int var42 = 4; var42 < serviceContext.length; ++var42) {
                    partIds.add(serviceContext[var42]);
                }

                currentPartIds.set(partIds);
            }
        }

        try {
            Object[] var38 = this.getParameters(cycle);
            cycle.setServiceParameters(var38);
            String var41 = "";
            var40 = "";
            IDataset var45 = null;
            DataMap var44 = null;
            if(pageName != null && !"".equals(pageName.trim())) {
                BasePage var46 = (BasePage)cycle.getPage(pageName);
                cycle.activate(var46);
                if(eventName != null && !"".equals(eventName.trim())) {
                    IActionListener var48 = (IActionListener)var46.getListeners().getListener(eventName);
                    var48.actionTriggered(var46, var46.getRequestCycle());
                }

                var46.pageBeforeRender();
                var40 = cycle.getAttribute("XMLDATA") == null?"":cycle.getAttribute("XMLDATA").toString();
                cycle.removeAttribute("XMLDATA");
                var41 = cycle.getAttribute("AJAXDATA") == null?"":cycle.getAttribute("AJAXDATA").toString();
                cycle.removeAttribute("AJAXDATA");
                BaseData var49 = var46.getBaseData();
                if(var49 != null) {
                    var45 = var49.getAjaxDataset();
                }

                currentPartIds.set(partIds2);
                partIds = partIds2;
                if(var49 != null) {
                    var45 = var49.getAjaxDataset();
                    currentPartIds.set(partIds2);
                    partIds = partIds2;
                    IData w = var49.getTransferData();
                    if(w != null) {
                        String[] tfDataHeader = w.getNames();
                        if(tfDataHeader.length > 0) {
                            var44 = new DataMap();

                            for(int tfDataFooter = 0; tfDataFooter < tfDataHeader.length; ++tfDataFooter) {
                                Object jsonHeader = w.get(tfDataHeader[tfDataFooter]);
                                if(jsonHeader != null) {
                                    if(jsonHeader instanceof String[]) {
                                        jsonHeader = ((String[])((String[])jsonHeader))[0];
                                    }

                                    if(jsonHeader != null && !"".equals(jsonHeader)) {
                                        var44.put(tfDataHeader[tfDataFooter], jsonHeader.toString());
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                direct.trigger(cycle);
            }

            if(partIds != null) {
                currentPartIds.set(Collections.unmodifiableSet(partIds));
                HashMap var47 = new HashMap();
                Iterator var50 = partIds.iterator();

                while(var50.hasNext()) {
                    String var51 = (String)var50.next();
                    var47.put(var51, new PartWriter(var51));
                }

                currentPartWriters.set(var47);
                output.setDiscard(true);
                engine.renderResponse(cycle, output);
                output.setDiscard(false);
                output.setContentType("text/xml");
                header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><parts>";
                output.write(header.getBytes("utf-8"));
                HTMLWriter var52 = new HTMLWriter(output);
                Iterator var53 = var47.values().iterator();

                while(var53.hasNext()) {
                    PartWriter var55 = (PartWriter)var53.next();
                    var55.write(var52);
                }

                var52.flush();
                String var54 = "<TRANSFERDATA id=\"tfdata\">";
                output.write(var54.getBytes("utf-8"));
                if(var44 != null) {
                    String[] var56 = var44.getNames();

                    for(int var58 = 0; var58 < var56.length; ++var58) {
                        output.write(("<TFDATAITEM name=\"" + var56[var58] + "\"><![CDATA[" + filterString(var44.getString(var56[var58])) + "]]></TFDATAITEM>").getBytes("utf-8"));
                    }
                }

                String var57 = "</TRANSFERDATA>";
                output.write(var57.getBytes("utf-8"));
                String jsonFooter;
                String var59;
                if(var40 != null && var40 != "") {
                    var59 = "<XMLDATA id=\"xmldata\">";
                    output.write(var59.getBytes("utf-8"));
                    output.write(filterString(var40).getBytes("utf-8"));
                    jsonFooter = "</XMLDATA>";
                    output.write(jsonFooter.getBytes("utf-8"));
                }

                var59 = "<JSONDATA id=\"json\"><![CDATA[";
                output.write(var59.getBytes("utf-8"));
                output.write(filterString(var41).getBytes("utf-8"));
                jsonFooter = "]]></JSONDATA>";
                output.write(jsonFooter.getBytes("utf-8"));
                String datasetHeader = "<DATASETDATA id=\"dataset\"><![CDATA[";
                output.write(datasetHeader.getBytes("utf-8"));
                if(var45 != null && var45.size() > 0) {
                    output.write(filterString(var45.toString()).getBytes("utf-8"));
                }

                String datasetFooter = "]]></DATASETDATA>";
                output.write(datasetFooter.getBytes("utf-8"));
                String footer = "</parts>";
                output.write(footer.getBytes("utf-8"));
                return;
            }

            engine.renderResponse(cycle, output);
        } catch (Exception var35) {
            log.error(var35);
            return;
        } finally {
            currentPartIds.set((Object)null);
            currentPartWriters.set((Object)null);
        }

    }

    private static String filterString(String str) {
        if(str != null && !str.equals("")) {
            String patternStr = "[^0-9a-zA-Z一-龥　-〿\uff00-\uffef_~!=@#%&*<>.,\':;\"\\s\\|\\/\\?\\-\\+\\[\\]\\{\\}\\(\\)]";
            str = str.replaceAll(patternStr, "");
            return str;
        } else {
            return "";
        }
    }

    public static boolean isPartialRender() {
        return currentPartIds.get() != null;
    }

    public static Set getPartIds() {
        return (Set)currentPartIds.get();
    }

    public static IMarkupWriter getPartWriter(String partId) {
        Map parts = (Map)currentPartWriters.get();
        if(parts == null) {
            return null;
        } else {
            PartWriter p = (PartWriter)parts.get(partId);
            return p == null?null:p.markupWriter;
        }
    }

    protected IComponent checkComponentContainers(IComponent comp) {
        if(comp == null) {
            return null;
        } else {
            for(IComponent parent = comp; parent.getContainer() != null; parent = parent.getContainer()) {
                ;
            }

            return comp;
        }
    }

    protected String getComponentId(IComponent comp) {
        String id = null;
        if(comp instanceof IFormComponent) {
            ;
        }

        if(comp instanceof IFormComponent) {
            id = ((IFormComponent)comp).getId();
        }

        if(id != null) {
            return id;
        } else {
            id = comp.getId();
            if(comp.getBinding("id") != null && comp.getBinding("id").getObject() != null) {
                id = comp.getBinding("id").getObject().toString();
            }

            return id;
        }
    }

    public IMarkupWriter getComponentWriter(String id, IMarkupWriter writer) {
        IMarkupWriter w = (IMarkupWriter)this.writers.get(id);
        if(w != null) {
            return w;
        } else {
            IMarkupWriter nestedWriter = writer.getNestedWriter();
            this.writers.put(id, nestedWriter);
            return nestedWriter;
        }
    }

    private static class PartWriter {
        final String id;
        final StringWriter stringWriter;
        final IMarkupWriter markupWriter;

        public PartWriter(String partId) {
            this.id = partId;
            this.stringWriter = new StringWriter();
            this.markupWriter = new HTMLWriter(new PrintWriter(this.stringWriter));
        }

        public void write(IMarkupWriter writer) {
            writer.begin("part");
            writer.attribute("id", this.id);
            this.markupWriter.flush();
            writer.print(this.stringWriter.toString());
            writer.end();
        }
    }
}
